package model

import (
	"errors"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"html"
	"strings"
)

type User struct {
	gorm.Model
	Username string ` gorm:"size:255;not null;unique" json:"username"`
	Password string ` gorm:"size:255;not null" json:"password"`
}

func (u *User) PrepareGive() {
	u.Password = ""
}
func GetUserByID(uid uint) (User, error) {
	var u User
	if err := DB.First(&u, uid).Error; err != nil {
		return u, errors.New("user not found")
	}
	u.PrepareGive()
	return u, nil
}

func (u *User) SaveUser() (*User, error) {
	err := DB.Create(&u).Error
	if err != nil {
		return &User{}, err
	}
	return u, nil
}
func (u *User) BeforeSave(tx *gorm.DB) error {
	hashedPasswd, err := bcrypt.GenerateFromPassword([]byte(u.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	u.Password = string(hashedPasswd)
	u.Username = html.EscapeString(strings.TrimSpace(u.Username))
	return nil
}
func LoginCheck(username, password string) (string, error) {
	var err error
	u := User{}

	err = DB.Model(User{}).Where("username = ?", username).Take(&u).Error
	if err != nil {
		return "", err
	}
	err = VerifyPassword(password, u.Password)
	if err != nil && errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
		return "", err
	}

	token, err := GenerateToken(u.ID)
	if err != nil {
		return "", err
	}
	return token, nil
}

func VerifyPassword(password string, password2 string) error {
	return bcrypt.CompareHashAndPassword([]byte(password2), []byte(password))
}
